<script lang="ts" setup>
  import { ref, onMounted } from 'vue';
  import { Game } from '@/types/game';
  import { MpCard } from '@/types/mp';
  import _ from 'lodash';
  import { Form, RequestOption, Message } from '@arco-design/web-vue';
  import { uploadImage } from '@/api/common';
  import { CourseItem } from '@/types/course';
  import { CmsArticle } from '@/types/cms';
  import { getGameList, getCourseList } from '@/api/game';
  import { createMpCard, updateMpCard } from '@/api/mp';
  import { getArticleList } from '@/api/cms';

  const props = defineProps<{
    posType: string;
    mpCard: Partial<MpCard>;
  }>();
  const emit = defineEmits(['close']);

  const gameList = ref<Game[]>([]);
  const handleSearchGame = async (value: string) => {
    try {
      const res = await getGameList({
        pageIndex: 1,
        pageSize: 50,
        name: value,
        approveStates: [1],
      });
      gameList.value = res.data.data.list || [];
    } finally {
      // do nothing
    }
  };

  const courseList = ref<CourseItem[]>([]);
  const handleSearchCourse = async (value: string) => {
    try {
      const res = await getCourseList({
        pageIndex: 1,
        pageSize: 50,
        content: value,
      });
      courseList.value = res.data.data.list || [];
    } finally {
      // do nothing
    }
  };

  const articleList = ref<CmsArticle[]>([]);
  const handleSearchArticle = async (value: string) => {
    try {
      const res = await getArticleList({
        pageIndex: 1,
        pageSize: 50,
        articleTitle: value,
        state: 1,
      });
      articleList.value = res.data.data.list || [];
    } finally {
      // do nothing
    }
  };

  const sizeMap = {
    pic: 1.5 * 1024 * 1024,
  };

  const customUploadImage = (options: RequestOption) => {
    const { fileItem, onError, onSuccess, name } = options;

    const continueUpload = async () => {
      const fd = new FormData();
      fd.append('upload', fileItem.file as File);
      try {
        const res = await uploadImage(fd, new AbortController());
        onSuccess(res.data.data);
      } catch (err) {
        onError('上传失败');
      }
    };

    if (fileItem.file) {
      if (fileItem.file.size > sizeMap[name as keyof typeof sizeMap]) {
        onError('图片尺寸过大');
        Message.error('图片尺寸过大');
      } else {
        continueUpload();
      }
    }

    return {};
  };

  const data = ref<Partial<MpCard>>({});
  onMounted(() => {
    if (props.mpCard.id) {
      data.value = _.clone(props.mpCard);

      if (data.value.pic) {
        data.value.picFileList = [
          {
            status: 'done',
            uid: data.value.pic,
            url: data.value.pic,
            response: data.value.pic,
          },
        ];
      }

      handleSearchGame(props.mpCard.title || '');
      handleSearchCourse(props.mpCard.title || '');
      handleSearchArticle(props.mpCard.title || '');
    } else {
      data.value.posType = props.posType;
      if (props.posType === 'CMS') {
        data.value.type = 'CMS';
      }
      handleSearchGame('');
      handleSearchCourse('');
      handleSearchArticle(props.mpCard.title || '');
    }
  });

  const handleTypeChange = () => {
    data.value.params = undefined;
  };

  const handleGameChanged = () => {
    data.value.title = gameList.value.find(
      (i) => i.id === data.value.params
    )?.name;
  };

  const handleCourseChanged = () => {
    data.value.title = courseList.value.find(
      (i) => i.id === data.value.params
    )?.name;
  };

  const handleArticleChange = () => {
    const article = articleList.value.find((i) => i.id === data.value.params);
    if (article) {
      data.value.title = article.articleTitle;
      if (article.coverUrl) {
        data.value.picFileList = [
          {
            status: 'done',
            uid: article.coverUrl,
            url: article.coverUrl,
            response: article.coverUrl,
          },
        ];
      }
    }
    data.value.title = articleList.value.find(
      (i) => i.id === data.value.params
    )?.articleTitle;
  };

  const saving = ref(false);
  const formRef = ref<InstanceType<typeof Form> | null>(null);
  const handleSubmit = async () => {
    if (formRef.value) {
      const validate = await formRef.value.validate();
      if (!validate) {
        try {
          saving.value = true;
          const mpCardCloned = _.cloneDeep(data.value);
          if (
            mpCardCloned.picFileList &&
            mpCardCloned.picFileList[0]?.status === 'done'
          ) {
            mpCardCloned.pic = mpCardCloned.picFileList[0]?.response;
            delete mpCardCloned.picFileList;
          } else {
            Message.error('请上传图片');
            return;
          }

          if (mpCardCloned.id) {
            await updateMpCard(mpCardCloned);
          } else {
            await createMpCard(mpCardCloned);
          }

          Message.success('操作成功');
          emit('close', true);
        } finally {
          saving.value = true;
        }
      }
    }
  };
</script>

<template>
  <a-drawer
    :title="mpCard.id ? '编辑' : '新建'"
    :width="500"
    visible
    :ok-loading="saving"
    @cancel="emit('close', false)"
    @before-ok="handleSubmit"
  >
    <div class="editor">
      <a-form ref="formRef" :model="data" layout="vertical">
        <a-form-item
          v-if="data.posType === 'CMS'"
          label="选择内容"
          field="params"
          :rules="[{ required: true, message: '请选择内容' }]"
        >
          <a-select
            v-model="data.params"
            :options="
              articleList.map((i) => ({ label: i.articleTitle, value: i.id }))
            "
            allow-search
            @search="handleSearchArticle"
            @change="handleArticleChange"
          ></a-select>
        </a-form-item>
        <a-form-item
          label="图片"
          field="picFileList"
          :rules="[{ required: true, message: '不能为空' }]"
        >
          <a-upload
            v-model:file-list="data.picFileList"
            list-type="picture-card"
            image-preview
            name="pic"
            :custom-request="customUploadImage"
            :limit="1"
          />
          <template #extra>
            {{
              data.posType !== 'SPONSOR'
                ? '请上传长宽比为5:3的图片，不大于1.5MB，建议尺寸1125*675'
                : '不大于1.5MB'
            }}
          </template>
        </a-form-item>

        <a-form-item
          v-if="data.posType !== 'SPONSOR'"
          label="类型"
          field="type"
          :rules="[{ required: true, message: '不能为空' }]"
        >
          <a-select
            v-model="data.type"
            :disabled="posType === 'CMS'"
            @change="handleTypeChange"
          >
            <a-option value="GAME">比赛</a-option>
            <a-option value="COURSE">球场</a-option>
            <a-option value="TRAINING" disabled>培训机构</a-option>
            <a-option value="TEACHER" disabled>教练</a-option>
            <a-option value="EQUIPMENT" disabled>装备详情页</a-option>
            <a-option value="LINK">公众号文章</a-option>
            <a-option value="CMS">学院内容</a-option>
            <a-option value="WX_VIDEO">视频号视频</a-option>
            <a-option value="WX_LIVE">视频号直播</a-option>
          </a-select>
        </a-form-item>

        <a-form-item
          v-if="data.type === 'GAME'"
          label="设置比赛"
          field="params"
          :rules="[{ required: true, message: '不能为空' }]"
        >
          <a-select
            v-model="data.params"
            :options="gameList.map((i) => ({ label: i.name, value: i.id }))"
            allow-search
            @search="handleSearchGame"
            @change="handleGameChanged"
          ></a-select>
        </a-form-item>

        <a-form-item
          v-if="data.type === 'COURSE'"
          label="设置球场"
          field="params"
          :rules="[{ required: true, message: '请设置球场' }]"
        >
          <a-select
            v-model="data.params"
            :options="courseList.map((i) => ({ label: i.name, value: i.id }))"
            allow-search
            @search="handleSearchCourse"
            @change="handleCourseChanged"
          ></a-select>
        </a-form-item>

        <a-form-item
          v-if="data.posType !== 'CMS' && data.type === 'CMS'"
          label="选择内容"
          field="params"
          :rules="[{ required: true, message: '请选择内容' }]"
        >
          <a-select
            v-model="data.params"
            :options="
              articleList.map((i) => ({ label: i.articleTitle, value: i.id }))
            "
            allow-search
            @search="handleSearchArticle"
            @change="handleArticleChange"
          ></a-select>
        </a-form-item>

        <a-form-item
          v-if="data.posType !== 'SPONSOR'"
          label="标题"
          field="title"
          :rules="[{ required: true, message: '请输入标题' }]"
        >
          <a-input v-model="data.title" />
        </a-form-item>

        <a-form-item
          v-if="data.posType !== 'SPONSOR'"
          label="副标题"
          field="subtitle"
        >
          <a-input v-model="data.subtitle" />
        </a-form-item>

        <a-form-item
          v-if="data.type === 'LINK'"
          label="公众号文章URL"
          field="params"
          :rules="[{ required: true, message: '不能为空' }]"
        >
          <a-input v-model="data.params" />
        </a-form-item>

        <a-form-item
          v-if="data.type === 'WX_VIDEO'"
          label="视频号视频ID"
          field="params"
          :rules="[{ required: true, message: '不能为空' }]"
        >
          <a-input v-model="data.params" />
        </a-form-item>

        <a-form-item
          v-if="data.posType === 'SPONSOR'"
          label="赞助商名称"
          field="title"
          :rules="[{ required: true, message: '请输入名称' }]"
        >
          <a-input v-model="data.title" />
        </a-form-item>
      </a-form>
    </div>
  </a-drawer>
</template>

<style lang="less" scoped>
  .editor {
    &:deep(.arco-upload-list-picture) {
      width: 300px;
      height: 180px;
    }
    &:deep(.arco-upload-picture-card) {
      width: 300px;
      height: 180px;
    }
    &:deep(.arco-upload-list-picture-mask) {
      line-height: 180px;
    }
  }
</style>
